package com.umbacos.udm.client.arch;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Grid;

public class Table extends Grid implements ContextMenu.EventHandler {

	public interface EventHandler {
		public void buildContextMenuCallback(ContextMenuList popup);

		public void clickCallback(int rowIndex, int cellIndex);

		public void contextMenuClickCallback(int command, int rowIndex,
				int cellIndex);
	}
	private EventHandler handlerOwner = null;
	private Element hovered = null;
	private int hRowIndex = -1;
	public boolean selectable = true;

	private int selected = -1;

	public boolean toggleSelectable = false;

	public Table() {
		super();
		sinkEvents(Event.ONMOUSEOVER + Event.ONMOUSEOUT + Event.ONCONTEXTMENU
				+ Event.ONCLICK);
	}

	public void addEventHandler(EventHandler handlerOwner) {
		this.handlerOwner = handlerOwner;
	}

	public void contextMenuClickCallback(int command, int rowIndex,
			int cellIndex) {
		if (handlerOwner == null)
			return;
		handlerOwner.contextMenuClickCallback(command, rowIndex, cellIndex);
	}

	public int getSelected() {
		return selected;
	}

	@Override
	public void onBrowserEvent(Event event) {
		Element td = getEventTargetCell(event);
		if (td == null)
			return;
		Element tr = DOM.getParent(td);
		int c = DOM.getElementPropertyInt(td, "cellIndex");
		int r = DOM.getElementPropertyInt(tr, "rowIndex");

		switch (DOM.eventGetType(event)) {
		case Event.ONMOUSEOVER:
			if (hovered != null)
				if (hRowIndex != selected)
					hovered.removeClassName("hovered");
			if (r != selected)
				tr.addClassName("hovered");
			hovered = tr;
			hRowIndex = r;
			break;
		case Event.ONMOUSEOUT:
			tr.removeClassName("hovered");
			break;
		case Event.ONCLICK:
			setSelected(r);
			if (handlerOwner == null)
				return;
			handlerOwner.clickCallback(r, c);
			break;
		case Event.ONCONTEXTMENU:
			setSelected(r);
			if (handlerOwner == null)
				return;
			ContextMenu popup = new ContextMenu();
			popup.addEventHandler(this);
			popup.setRowIndex(r);
			popup.setCellIndex(c);
			handlerOwner.buildContextMenuCallback(popup);
			if (popup.getMenuItemCount() == 0)
				return;
			popup.setPopupPosition(event.getClientX(), event.getClientY());
			popup.show();
			event.stopPropagation();
			event.preventDefault();
			break;
		default:
			break;
		}
	}

	public void setSelected(final int selected) {
		if (!selectable)
			return;

		if ((this.selected != -1) && (this.selected>=0) && (this.selected<getRowCount()))
			getRowFormatter().removeStyleName(this.selected, "selected");

		if (selected == -1)
			return;

		if (this.selected != selected) {
			getRowFormatter().addStyleName(selected, "selected");
			this.selected = selected;
		} else {
			if (toggleSelectable) {
				this.selected = -1;
			} else {
				getRowFormatter().addStyleName(selected, "selected");
				this.selected = selected;
			}
		}
	}
}
